<template>
  <div class="w-full flex justify-center relative">
    <Transition name="swiper">
      <div
        :key="timeText"
        ref="timeRef"
        :style="{ color: statueColor }"
        class="time-text absolute -top-[30px] left-[calc(50%+30px)]"
      >
        {{ timeText }}
      </div>
    </Transition>
    <div class="w-[180px] h-[180px] relative">
      <div class="w-full h-full star-path relative"></div>
      <div class="star-fill w-full h-full absolute left-0 top-0 z-10"></div>
    </div>
  </div>
</template>
<script lang="ts" setup name="HuXiBall">
import { playerHuQiAudio, playerYaQiAudio, playerXiuQiAudio } from "@/utils/player";
import { IHuXiConfig, BreatheEnum, getStatusColor } from "../utils";
import { withDefaults, reactive, watch, ref, computed, onUnmounted, onMounted, toRefs } from "vue";
import { gsap } from "gsap";

const timeRef = ref<HTMLDivElement>();
const timeText = ref("");
const toolpText = ref<BreatheEnum>(BreatheEnum.absorb);
const props = withDefaults(
  defineProps<{
    huxiConfig: IHuXiConfig;
    isPlay: boolean;
    isRenSheng?: boolean;
  }>(),
  {
    isRenSheng: true,
  }
);
const { isPlay, isRenSheng } = toRefs(props);
const starRef = reactive({
  x: 0,
  count: 1,
  scale: 1,
});

const emit = defineEmits<{
  next: [];
  onRepeat: [count: number];
  onStart: [value: BreatheEnum];
}>();

const starFillProgress = computed(() => {
  return Math.ceil(starRef.x) + "%";
});
const scale = computed(() => {
  return starRef.scale;
});
const timeLine = gsap.timeline({
  repeat: -1,
  paused: true,
  onRepeat() {
    starRef.count++;
    emit("onRepeat", starRef.count);
  },
});

const statueColor = computed(() => {
  return getStatusColor(toolpText.value);
});

function playRenSheng() {
  if (!isRenSheng.value) {
    return;
  }

  switch (toolpText.value) {
    case BreatheEnum.absorb:
      playerXiuQiAudio();
      break;
    case BreatheEnum.stop:
      playerYaQiAudio();
      break;
    case BreatheEnum.reset:
      playerHuQiAudio();
      break;
  }
}

function run() {
  setTimeout(() => {
    timeLine.clear();
    timeLine.to(starRef, {
      duration: props.huxiConfig.absorbDuration,
      x: 100,
      label: "absorb",
      transformOrigin: "center",
      onUpdateParams: [],

      onStart() {
        toolpText.value = BreatheEnum.absorb;
        emit("onStart", BreatheEnum.absorb);
        playRenSheng();
        nextText();
      },
      onUpdate() {
        setTimeValue(this);
      },
    });
    timeLine.to(starRef, {
      duration: props.huxiConfig.stopDuration,
      label: "stop",
      x: 100,
      scale: 1.3,
      transformOrigin: "center",

      onStart() {
        toolpText.value = BreatheEnum.stop;
        playRenSheng();
        emit("onStart", BreatheEnum.stop);
      },
      onUpdate() {
        setTimeValue(this);
      },
    });
    timeLine.to(starRef, {
      duration: props.huxiConfig.resetDuration,
      label: "reset",
      x: 0,
      scale: 1,
      transformOrigin: "center",
      onStart() {
        toolpText.value = BreatheEnum.reset;
        emit("onStart", BreatheEnum.reset);

        playRenSheng();
        nextText();
      },
      onUpdate() {
        setTimeValue(this);
      },
    });
  }, 100);
}

function distroy() {
  timeLine.kill();
}

function setTimeValue(tl: gsap.TweenVars) {
  timeText.value = `${toolpText.value} +${Math.ceil(tl.time())}s`;
}

function nextText() {
  if (isPlay.value) {
    emit("next");
  }
}

function paly() {
  timeLine.play();
}

function stop() {
  // timeLine.pause();
  // timeLine.revert();
  timeLine.progress(0).pause();
  timeText.value = "";
}

watch(isPlay, (value, oldValue) => {
  if (value) {
    paly();
  } else {
    stop();
  }
});

watch(
  props.huxiConfig,
  () => {
    run();
  },
  {
    deep: true,
  }
);
onMounted(() => {
  run();
});
onUnmounted(() => {
  distroy();
});
</script>

<style lang="scss" scoped>
.star-path {
  mask: url("../assets/star.svg");
  mask-image: url("../assets/star.svg");
  background-color: #60a5fa;
}

.star-fill {
  mask: url("../assets/star-fill.svg");
  mask-image: url("../assets/star-fill.svg");
  background-image: linear-gradient(
    0deg,
    #ffcc70 0%,
    #ffcc70 v-bind(starFillProgress),
    transparent v-bind(starFillProgress)
  );
}
</style>
